package com.pijjunn.label

import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.transaction.annotation.Transactional;

import com.pijunn.label.Label;
import com.pijunn.label.LabeledItem;

class LabelService {

	def springSecurityService
	
	/**
	 * Users manage their labels in groups
	 * @param labelList
	 * @return
	 */
    def saveLabels(labelList) {

       for (labeledItemInstance in labelList) {
		   
	        if (!labeledItemInstance.save(flush: true)) {
	            return false
	        }
			
			Label label = labeledItemInstance.label
			if (!label.registeredTo) {
				label.registeredTo = springSecurityService.getCurrentUser()
				label.registrationDate = new Date()
				
				if (!label.save(flush: true)) {
					return false
				}
			}
	    }
	   
	   true
    }
	
	def removeItem(item) {
		def label = item.label
		label.removeFromItem(item)

		try {
			item.delete(flush: true)
			if (!label.assigned) {
				label.registeredTo = null
				label.save(flush: true)
			}
		}
		catch (DataIntegrityViolationException e) {
			return false
		}
			
		return true
	}
	
	// Convenience Queries
	@Transactional(readOnly = true)
	def getMyItems() {
		def user = springSecurityService.currentUser
		
		return LabeledItem.withCriteria {
			label {
				eq ('registeredTo', user)
			}
		}
	}

	@Transactional(readOnly = true)
	def getMyAvailableLabels() {
		def user = springSecurityService.currentUser
		
		return Label.findAllByRegisteredTo(user).findAll { !it.item }
	}
	
	@Transactional(readOnly = true)
	def getCountsForProperty(def property) {
		return Label.withCriteria {
			projections {
				groupProperty property
				rowCount()
			}
		}
	}
	
	@Transactional(readOnly = true)
	def getItemCountsForProperty(def property) {
		return LabeledItem.withCriteria {
			label {
				projections {
					groupProperty property
					rowCount()
				}
			}
		}
	}
	
	@Transactional(readOnly = true)
	def getRegisteredCountsForProperty(def property) {
		return Label.withCriteria {
			isNotNull('registeredTo')
			projections {
				groupProperty property
				rowCount()
			}
		}
	}
}
